#ifndef DYN_ROOTS_MULTIDIM_STA_H
#define DYN_ROOTS_MULTIDIM_STA_H

#include "dyn_roots.h"
#include "../utilities/dyn_multifunctor_multiMaps.h"

using namespace arma;

/*! \brief This class defines the Stability Transform
 * Algorithm for multi-dimensional systems.
 */

class MultiSTA : public RootFinding
{
    friend class STAFlow;
public:
    /*! The constructor sets the basic parameters
     * of the ST algorithm.
     */
    MultiSTA(MultiMaps& map,
             colvec init,
             const double tol,
             const double para,
             const int p,
             const int Nmax);

    /*! @name Accessor functions.
     * We define specialized accessor functions.
     */
    //@{
    virtual MultiMaps& getMultiMaps(){return multiMap;}
    virtual colvec getm_InitialValue(){return m_initialValue;}
    virtual mat getFixedPoints(){return fixedPoints;}
    virtual double getLambda(){return lambda;}
    virtual int getPeriod(){return period;}
    virtual cube getReflectionMatrices(){return reflectionMatrices;}

    virtual void setMultiMaps(MultiMaps& mMap){multiMap = mMap;}
    virtual void setm_InitialValue(mat init){m_initialValue = init;}
    virtual void setLambda(double para){lambda = para;}
    virtual void setPeriod(int p){period = p;}
    virtual void setReflectionMatrices(cube reflect){reflectionMatrices=reflect;}
    //@}

    /*! We reimplement the solve() function. */
    int solve();

    /*! We define an iterate() function that simply
     * returns the correction for this point.
     */
    virtual colvec iterate(const colvec X,int sliceIndex=1);

    /*! @name Reflection matrices.
     * STA uses special matrices in the
     * transform dynamical system.
     * This function prepares them.
     */
    int prepareReflectionMatrices(int dim);


protected:
    /*! @name Specialized variables.
     * We define variables specialized for MultiSTA.
     * It takes a multi-dimensional maps, vector
     * initial conditions and returns a matrix of
     * fixed points.
     */
    //@{
    MultiMaps& multiMap;
    colvec m_initialValue;
    mat fixedPoints;
    double lambda;
    int period;
    cube reflectionMatrices;
    //@}
};

#endif // DYN_ROOTS_MULTIDIM_STA_H
